package utils

import (
	"encoding/json"
	"errors"
	"fmt"
	log "github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/rest/httpc"
	"godco/internal/svc"
	"io"
	"net/http"
	"strings"
)

type MarketInstallAppInfo struct {
	AccessTokensUrl     string         `json:"access_tokens_url"`
	Account             AppAccount     `json:"account"`
	AppId               int64          `json:"app_id"`
	AppSlug             string         `json:"app_slug"`
	CreatedAt           string         `json:"created_at"`
	Events              []string       `json:"events"`
	HtmlUrl             string         `json:"html_url"`
	Id                  int64          `json:"id"`
	Permissions         AppPermissions `json:"permissions"`
	RepositorySelection string         `json:"repository_selection"`
	TargetId            string         `json:"target_id"`
	TargetType          string         `json:"target_type"`
	UpdatedAt           string         `json:"updated_at"`
}

type AppAccount struct {
	Id    string `json:"id"`
	Login string `json:"login"`
	Type  string `json:"type"`
}

type AppPermissions struct {
	Emails                     string `json:"emails"`
	PullRequests               string `json:"pull_requests"`
	Followers                  string `json:"followers"`
	Checks                     string `json:"checks"`
	Contents                   string `json:"contents"`
	Keys                       string `json:"keys"`
	Meta                       string `json:"meta"`
	RepositoryHooks            string `json:"repository_hooks"`
	Statuses                   string `json:"statuses"`
	OrganizationAdministration string `json:"organization_administration"`
	Issues                     string `json:"issues"`
}

type MarketAppInfo struct {
	CreateAt    string         `json:"create_at"`
	Events      []string       `json:"events"`
	HtmlUrl     string         `json:"html_url"`
	Owner       AppOwner       `json:"owner"`
	Permissions AppPermissions `json:"permissions"`
	UpdatedAt   string         `json:"updated_at"`
}

type AppOwner struct {
	Id    string `json:"id"`
	Login string `json:"login"`
}

// 获取应用安装信息
func GetInstallationAppInfo(installationId string, svcCtx *svc.ServiceContext) (*MarketInstallAppInfo, error) {
	url := svcCtx.Config.ApplicationConf.AtomgitApi + "/app/installations/{installationId}"
	url = strings.Replace(url, "{installationId}", installationId, -1)
	r, err := http.NewRequest("GET", url, nil)
	if err != nil {
		log.Error(err)
		return nil, err
	}
	//Redis拿到该应用的token
	redisKey := "jwt_token_" + svcCtx.Config.Client.AppId
	jwtToken, _ := svcCtx.RedisClient.Get(redisKey)
	if jwtToken == "" {
		jwtToken = GetMarketAppJWTToken(svcCtx.Config.ApplicationConf.DcoPrivateKeyPem, svcCtx.Config.Client.AppId)
		svcCtx.RedisClient.Setex(redisKey, jwtToken, 3600*24)
	}
	// 设置请求头
	r.Header.Set("Content-Type", "application/json")
	r.Header.Set("Authorization", "Bearer "+jwtToken)
	res, err_ := httpc.DoRequest(r)
	if err_ != nil {
		log.Error(err_)
		return nil, err_
	}
	defer res.Body.Close()
	body, err := io.ReadAll(res.Body)
	if err != nil {
		log.Errorf("Failed to read response body:%s", err)
		return nil, err
	}
	log.Debug(res.StatusCode)
	if res.StatusCode >= 200 && res.StatusCode < 400 {
		var marketInstallAppInfo MarketInstallAppInfo
		err = json.Unmarshal(body, &marketInstallAppInfo)
		if err != nil {
			log.Errorf("Error unmarshalling response:%s", err.Error())
			return nil, err
		}
		return &marketInstallAppInfo, nil // 返回 User 的指针
	}
	return nil, errors.New("error, status: " + res.Status + " code: " + fmt.Sprintf("%d", res.StatusCode))
}

// 获取应用信息
func GetMarketAppInfo(svcCtx *svc.ServiceContext) (*MarketAppInfo, error) {
	url := svcCtx.Config.ApplicationConf.AtomgitApi + "/app"
	r, err := http.NewRequest("GET", url, nil)
	if err != nil {
		log.Error(err)
		return nil, err
	}
	//Redis拿到该应用的token
	redisKey := "jwt_token_" + svcCtx.Config.Client.AppId
	jwtToken, _ := svcCtx.RedisClient.Get(redisKey)
	if jwtToken == "" {
		jwtToken = GetMarketAppJWTToken(svcCtx.Config.ApplicationConf.DcoPrivateKeyPem, svcCtx.Config.Client.AppId)
		svcCtx.RedisClient.Setex(redisKey, jwtToken, 3600*24)
	}
	// 设置请求头
	r.Header.Set("Content-Type", "application/json")
	r.Header.Set("Authorization", "Bearer "+jwtToken)
	res, err_ := httpc.DoRequest(r)
	if err_ != nil {
		log.Error(err_)
		return nil, err_
	}
	defer res.Body.Close()
	body, err := io.ReadAll(res.Body)
	if err != nil {
		log.Errorf("Failed to read response body:%s", err)
		return nil, err
	}
	log.Debug(res.StatusCode)
	if res.StatusCode >= 200 && res.StatusCode < 400 {
		var marketAppInfo MarketAppInfo
		err = json.Unmarshal(body, &marketAppInfo)
		if err != nil {
			log.Errorf("Error unmarshalling response:%s", err.Error())
			return nil, err
		}
		return &marketAppInfo, nil // 返回 User 的指针
	}
	return nil, errors.New("error, status: " + res.Status + " code: " + fmt.Sprintf("%d", res.StatusCode))
}
